/*
 * Project: equity
 *
 * File Created at 2020/10/10
 *
 * Copyright 2018 CMCC Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ZYHY Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license.
 */
package cn.lxh.basic.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.util.StringUtils;

/**
 * @author luolei
 * @Type DateUtil
 * @Desc
 * @date 2020/10/10 17:12
 */
public class  DateUtil {

    private static final ConcurrentMap<String, DateTimeFormatter> FORMATTER_CACHE = new ConcurrentHashMap<>();
    private static final int PATTERN_CACHE_SIZE = 500;

    private static final SimpleDateFormat YMD_SDF = new SimpleDateFormat("yyyy-MM-dd");

    private static final SimpleDateFormat YM_SDF = new SimpleDateFormat("yyyy-MM");

    public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";
    public static final String PATTERN_YYYY_MM_DD = "yyyyMMdd HH:mm:ss";
    public static final String PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String PATTERN_YYYYMMDD = "yyyyMMdd";
    public static final String PATTERN_YYYYMM = "yyyyMM";
    public static final String PATTERN_RFC3339 = "yyyy-MM-dd'T'HH:mm:ssXXX";
    private static final DateTimeFormatter OF_PATTERN = DateTimeFormatter
            .ofPattern("yyyy-MM-dd HH:mm:ss");

    public static final String PATTERN_YYYYMMDDHH24MISS = "yyyyMMddHHmmss";

    /**
     * 获取每月第一天
     *
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DATE, 1);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }

    /**
     * @date 2023/7/3
     * @description: 获取某一天开始时间
     */
    public static Date getBeginOfDate(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return c.getTime();
    }


    /**
     * @date 2023/7/3
     * @description: 获取某一天结束时间
     */
    public static Date getEndOfDate(Date date){
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    public static Date getEndDayOfMonth(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        ca.set(Calendar.HOUR_OF_DAY, 23);
        ca.set(Calendar.MINUTE, 59);
        ca.set(Calendar.SECOND, 59);
        return ca.getTime();
    }


    /**
     * 获取当前月第一天
     *
     * @return
     */
    public static String currentFirstDay() {
        /*Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(c.getTime());*/
        return currentFirstDayM();
    }

    /**
     * 获取当前月第一天  0时0分0秒
     *
     * @return
     */
    public static String currentFirstDayM() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(c.getTime());
    }

    /**
     * 获取当前月最后一天  23时59分59秒
     *
     * @return
     */
    public static String currentLastDayM() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        ca.set(Calendar.HOUR_OF_DAY, 23);
        ca.set(Calendar.MINUTE, 59);
        ca.set(Calendar.SECOND, 59);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(ca.getTime());
    }

    /**
     * 获取某月的第一天 0时0分0秒
     *
     * @param month 偏移月数
     * @return
     */
    public static String monthFirstDay(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 1);//设置为1号
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.format(calendar.getTime());
    }

    /**
     * 获取当天 23时59分59秒时间戳
     *
     * @return
     */
    public static long currentLastM() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime().getTime();
    }

    /**
     * 获取当前年最后一天  23时59分59秒
     *
     * @return
     */
    public static String currentYearLastDayM() {
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.MONTH, 11);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        ca.set(Calendar.HOUR_OF_DAY, 23);
        ca.set(Calendar.MINUTE, 59);
        ca.set(Calendar.SECOND, 59);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String lastDay = format.format(ca.getTime());
        return lastDay;
    }

    /**
     * 获取当前月最后一天
     *
     * @return
     */
    public static String currentLastDay() {
        return currentLastDayM();
    }

    /**
     * 获得本周一与当前日期相差的天数
     */

    public static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 1) {
            return -6;
        } else {
            return 2 - dayOfWeek;
        }
    }

    /**
     * 获取当前周一的日期
     *
     * @return
     */
    public static Date getCurrentMonday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        Date monday = currentDate.getTime();
        return monday;
    }

    /**
     * 获取指定日期为周几
     * 返回1-7
     *
     * @param date
     * @return
     */
    public static int getDayOfWeek(Date date) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);

        //一周第一天是否为星期天
        boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY);
        //获取周几
        int weekDay = now.get(Calendar.DAY_OF_WEEK);
        //若一周第一天为星期天，则-1
        if (isFirstSunday) {
            weekDay = weekDay - 1;
            if (weekDay == 0) {
                weekDay = 7;
            }
        }
        return weekDay;
    }

    /**
     * 获取指定日期的周一那天日期
     *
     * @param date
     * @return
     */
    public static Date getMondayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (1 != dayWeek) {
            cal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int day = cal.get(Calendar.DAY_OF_WEEK);
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - day);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 指定日期进行加减
     *
     * @param date
     * @param field  Calendar.DAY_OF_MONTH
     * @param amount 负数为减
     * @return
     */
    private static Date add(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    /**
     * 指定时间进行分钟加减
     *
     * @param date
     * @param amount 负数为减
     * @return
     */
    public static Date dateAddMinute(Date date, int amount) {
        return add(date, Calendar.MINUTE, amount);
    }

    /**
     * 指定日期进行天数加减
     *
     * @param date
     * @param amount 负数为减
     * @return
     */
    public static Date dateAdd(Date date, int amount) {
        return add(date, Calendar.DAY_OF_MONTH, amount);
    }

    /**
     * 指定日期进行月份加减
     *
     * @param date
     * @param amount 负数为减
     * @return
     */
    public static Date dateAddMonth(Date date, int amount) {
        return add(date, Calendar.MONTH, amount);
    }

    /**
     * date转LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDate(Date date) {
        if (null == date) {
            return null;
        }
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * Date转String
     *
     * @param date
     * @return
     */
    public static String  dateToString(Date date, String partten) {
        if (null == date) {
            return null;
        }
        if (null == partten) {
            return YMD_SDF.format(date);
        }
        return new SimpleDateFormat(partten).format(date);
    }

    /**
     * String转LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime stringToLocalDate(String date) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        return LocalDateTime.parse(date, df);
    }

    /**
     * String转LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime stringToLocalDate(String date, String pattern) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern);

        return LocalDateTime.parse(date, df);
    }

    /**
     * 获取当前周六的日期
     *
     * @return
     */
    public static Date getCurrentSaturday() throws ParseException {
        int mondayPlus = getMondayPlus();
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 5);
        Date monday = currentDate.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.parse(sd.format(monday.getTime()) + " 00:00:00");
    }

    /**
     * 得到本周周日
     *
     * @return yyyy-MM-dd
     */
    public static Date getSundayOfThisWeek() throws ParseException {
        Calendar c = Calendar.getInstance();
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        c.add(Calendar.DATE, -dayOfWeek + 7);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return format.parse(sd.format(c.getTime()) + " 23:59:59");
    }

    /**
     * string格式时间转化为date格式
     *
     * @param strDate
     * @return
     */
    public static Date convertStrToDate(String strDate) {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        String partten = "yyyyMMdd";
        if (strDate.indexOf("-") > 0) {
            partten = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(partten);
        Date date = null;
        try {
            date = sdf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * string格式时间转化为date格式
     *
     * @param strDate
     * @return
     */
    public static Date convertStrToDate(String strDate, String partten) {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        if (StringUtils.isEmpty(partten)) {
            partten = "yyyyMMddHHmmss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(partten);
        Date date = null;
        try {
            date = sdf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * string格式时间转化为String格式
     *
     * @param strDate 时间
     * @param partten 格式
     * @return
     */
    public static String convertStrTostr(String strDate, String partten) {
        if (StringUtils.isEmpty(strDate)) {
            return null;
        }
        if (StringUtils.isEmpty(partten)) {
            partten = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(partten);
        Date date = null;
        try {
            date = sdf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return convertDateToStr(date, partten);
    }

    /**
     * 时间格式转化,string格式时间转化为String格式
     * @param time 时间
     * @param pattern 当前时间格式
     * @param newPattern 新的时间格式
     * @return 时间
     */
    public static String timeFormatConversion(String time, String pattern, String newPattern) {
        DateFormat dft = new SimpleDateFormat(pattern);
        DateFormat newDft = new SimpleDateFormat(newPattern);
        String newTime = null;
        try {
            newTime = newDft.format(dft.parse(time));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return newTime;
    }

    /**
     * string格式时间转化为date格式
     *
     * @param date
     * @return
     */
    public static String convertDateToStr(Date date) {
        return convertDateToStr(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * string格式时间转化为date格式
     *
     * @param date
     * @return
     */
    public static String convertDateToStr(LocalDateTime date) {
        if (date == null) {
            return null;
        }

        String dateStr = date.format(OF_PATTERN);
        return dateStr;
    }

    /**
     * Date格式时间转化为String格式
     *
     * @param date
     * @return
     */
    public static String convertDateToStr(Date date, String formatStr) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat formatTemp = new SimpleDateFormat(formatStr);
        String dateStr = formatTemp.format(date);
        return dateStr;
    }

    /**
     * 时间格式化
     *
     * @param localDateTime
     * @param pattern
     * @return
     */
    public static String format(LocalDateTime localDateTime, String pattern) {
        DateTimeFormatter formatter = createCacheFormatter(pattern);
        return localDateTime.format(formatter);
    }

    /**
     * 在缓存中创建DateTimeFormatter
     *
     * @param pattern 格式
     * @return DateTimeFormatter
     */
    private static DateTimeFormatter createCacheFormatter(String pattern) {
        if (pattern == null || pattern.length() == 0) {
            throw new IllegalArgumentException("Invalid pattern specification");
        }
        DateTimeFormatter formatter = FORMATTER_CACHE.get(pattern);
        if (formatter == null) {
            if (FORMATTER_CACHE.size() < PATTERN_CACHE_SIZE) {
                formatter = DateTimeFormatter.ofPattern(pattern);
                DateTimeFormatter oldFormatter = FORMATTER_CACHE.putIfAbsent(pattern, formatter);
                if (oldFormatter != null) {
                    formatter = oldFormatter;
                }
            }
        }
        return formatter;
    }

    private static final String PATTERN = "yyyyMMddHHmmss";

    private static final String PATTERN_DAY = "yyyyMMdd";

    /**
     * 时间戳按指定格式转化为日期（String）
     *
     * @param timestamp
     * @return
     */
    public static String convertTimestamp2Date(Long timestamp) {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN);

        return simpleDateFormat.format(new Date(timestamp));
    }

    public static String convertTimestamp2Day(Long timestamp) {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(PATTERN_DAY);

        return simpleDateFormat.format(new Date(timestamp));
    }

    /**
     * 获取一天中剩余的时间（秒数）
     */
    public static Integer getDayRemainingTime(Date currentDate) {
        LocalDateTime midnight = LocalDateTime
                .ofInstant(currentDate.toInstant(), ZoneId.systemDefault()).plusDays(1).withHour(0)
                .withMinute(0).withSecond(0).withNano(0);
        LocalDateTime currentDateTime = LocalDateTime.ofInstant(currentDate.toInstant(),
                ZoneId.systemDefault());
        long seconds = ChronoUnit.SECONDS.between(currentDateTime, midnight);
        return (int) seconds;
    }

    /**
     * 获取当天凌晨0点0分0秒Date
     *
     * @param day 偏移天数
     * @return
     */
    public static Date firstSecondDate(int day) {
        Calendar calendar1 = Calendar.getInstance();
        if (day != 0) {
            calendar1.add(Calendar.DAY_OF_MONTH, day);
        }
        calendar1.set(calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH),
                calendar1.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        Date beginOfDate = calendar1.getTime();
        return beginOfDate;
    }

    /**
     * 获取当天零点日期
     *
     * @return
     */
    public static Date getZeroClockOfToday() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取当天凌晨23点59分59秒Date
     *
     * @param day 偏移天数
     * @return
     */
    public static Date lastSecondDate(int day) {
        Calendar calendar1 = Calendar.getInstance();
        if (day != 0) {
            calendar1.add(Calendar.DAY_OF_MONTH, day);
        }
        calendar1.set(calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH),
                calendar1.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        Date beginOfDate = calendar1.getTime();
        return beginOfDate;
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    /**
     * 日期格式转换 20210823150700 到 2021-04-16 16:09:22
     *
     * @param str
     * @return
     */
    public static String formatDateStr(String str) {
        try {
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = sdf2.parse(str);
            return sdf1.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return str;
        }
    }

    /**
     * 比较两个时间的相差月份
     *
     * @param startDate 开始日期
     * @param endDate   比较日期
     * @return
     */
    public static Integer getDifMonth(Date startDate, Date endDate) {

        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();

        start.setTime(startDate);
        end.setTime(endDate);

        int result = end.get(Calendar.MONTH) - start.get(Calendar.MONTH);
        int month = (end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) * 12;

        return Math.abs(month + result);
    }

    /**
     * 近七天 不包含今天
     *
     * @return
     */
    public static List<String> getSevenDate() {
        List<String> dateList = new ArrayList<>();

        for (int i = 1; i < 8; i++) {
            Date date = DateUtils.addDays(new Date(), -i);
            String formatDate = YMD_SDF.format(date);
            dateList.add(formatDate);
        }
        return dateList;
    }

    /**
     * 计算两者时间的日期
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static List<String> getBothOfDay(Date startTime, Date endTime) {
        List<String> dateList = new ArrayList<>();

        if (startTime == null && endTime == null) {
            return dateList;
        } else if (startTime == null && endTime != null) {
            dateList.add(YMD_SDF.format(endTime));
            return dateList;
        } else if (startTime != null && endTime == null) {
            dateList.add(YMD_SDF.format(startTime));
            return dateList;
        }

        long days = (endTime.getTime() - startTime.getTime() + 1000000) / (3600 * 24 * 1000);

        for (int i = 0; i <= days; i++) {
            Date date = DateUtils.addDays(startTime, i);
            String formatDate = YMD_SDF.format(date);
            dateList.add(formatDate);
        }
        return dateList;
    }

    /**
     * 计算两者时间之间的月份
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static List<String> getBothOfMonth(String startTime, String endTime) {

        List<String> strings = new ArrayList<>();

        Calendar startDate = Calendar.getInstance();
        Calendar endDate = Calendar.getInstance();
        try {
            startDate.setTime(YMD_SDF.parse(startTime));
            endDate.setTime(YMD_SDF.parse(endTime));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        String endYm = YM_SDF.format(endDate.getTime());
        while (true) {
            String strYm = YM_SDF.format(startDate.getTime());
            strings.add(strYm);
            System.out.println(strYm);
            if (strYm.equals(endYm)) {
                break;
            }
            startDate.add(Calendar.MONTH, 1);
        }

        return strings;
    }

    /**
     * 计算两者时间的日期
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return
     */
    public static List<String> getBothOfDay(String startTime, String endTime) {
        List<String> dateList = new ArrayList<>();

        if (org.apache.commons.lang3.StringUtils.isBlank(startTime)
                && org.apache.commons.lang3.StringUtils.isBlank(endTime)) {
            return dateList;
        } else if (org.apache.commons.lang3.StringUtils.isBlank(startTime)
                && org.apache.commons.lang3.StringUtils.isNotBlank(endTime)) {
            dateList.add(endTime);
            return dateList;
        } else if (org.apache.commons.lang3.StringUtils.isNotBlank(startTime)
                && org.apache.commons.lang3.StringUtils.isBlank(endTime)) {
            dateList.add(startTime);
            return dateList;
        }

        Date startTime1 = null;

        Date endTime1 = null;
        try {
            startTime1 = YMD_SDF.parse(startTime);
            endTime1 = YMD_SDF.parse(endTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        long days = (endTime1.getTime() - startTime1.getTime() + 1000000) / (3600 * 24 * 1000);

        for (int i = 0; i <= days; i++) {
            Date date = DateUtils.addDays(startTime1, i);
            String formatDate = YMD_SDF.format(date);
            dateList.add(formatDate);
        }
        return dateList;
    }

    /**
     * 获取当月到目昨天之间的日期
     *
     * @return
     */
    public static List<String> getBothOfYesterdayAndMonth() {
        Date date = new Date();

        Date firstDayOfMonth = DateUtil.getFirstDayOfMonth(date);

        List<String> day = getBothOfDay(firstDayOfMonth, new Date());

        if (day.size() >= 2) {
            day.remove(day.size() - 1);
        }

        return day;
    }

    /**
     * 获取昨天日期
     *
     * @return
     */
    public static String getYesterday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        String yesterday = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(cal.getTime());
        return yesterday;
    }

    /**
     * 会话ID生成
     *
     * @return
     */
    public static String getTransactionID() {
        String sb = convertDateToStr(new Date(), "yyyyMMddHHmmssSSS")
                + RandomStringUtils.randomNumeric(15);
        return sb;
    }

    /**
     * 获取当前年月字符串
     *
     * @return
     */
    public static String getyyyyMMStr() {
        return convertDateToStr(new Date(), "yyyyMM");
    }

    /**
     * @date: 2022年04月20
     * @description 获取当天0点的时间-localDateTime
     */
    public static LocalDateTime getFirstLocalDateTime() {
        return LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
    }

    /**
     * 转换类型 string to LocalDateTime
     *
     * @param time time
     * @return LocalDateTime
     */
    public static LocalDateTime parseDate(String time) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);
        return LocalDateTime.of(LocalDate.parse(time, formatter), LocalTime.MIN);
    }

    /**获取开始 结束时间
     * @param isStart
     * @return
     */
    public static LocalDateTime getYerDayStartEnd(boolean isStart) {

        LocalDateTime startTime = LocalDate.now().atStartOfDay().plusDays(-1);
        LocalDateTime endTime = LocalDateTime.of(LocalDate.now().plusDays(-1), LocalTime.MAX);
        if (isStart) {
            return startTime;
        } else {
            return endTime;
        }

    }

    /**
     * date 转换到 LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime convertDate2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * localtime
     *
     * @param date
     * @return
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 比较两个时间是不是同一天
     * @param startDate 开始日期
     * @param endDate   比较日期
     * @return
     */
    public static boolean isSameDate(Date startDate, Date endDate) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(startDate);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(endDate);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);

        boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);

        boolean isSameDate = isSameMonth
                && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);

        return isSameDate;
    }

    /**
     * 获取前一天天零点日期
     *
     * @return
     */
    public static Date getZeroClockOfYesterday() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * localDateTime转Date
     *
     * @param localDateTime
     * @return
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * @param localDate
     * @return
     */
    public static Date localDateToDate(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    /**
     * 对date向上取value2-1 Days/Hours/Minutes(5 10 20 30)
     *
     * @param date
     * @param value1
     * @param value2
     * @return
     */
    public static Date getCountDate(Date date, String value1, String value2) {
        Objects.requireNonNull(date);
        Objects.requireNonNull(value1);
        Objects.requireNonNull(value2);
        LocalDateTime localDateTime = dateToLocalDateTime(date);
        Integer val = Integer.valueOf(value2);
        LocalDateTime ceilTime = null;
        switch (value1) {
            case "DAY":
                ceilTime = localDateTime.minusDays(val - 1).withHour(0).withMinute(0).withSecond(0)
                        .withNano(0);
                break;
            case "HOUR":
                ceilTime = localDateTime.minusHours(val - 1).withMinute(0).withSecond(0)
                        .withNano(0);
                break;
            case "MINUTE":
                ceilTime = localDateTime.minusMinutes(val);

                break;
            default:
                break;
        }
        return Objects.isNull(ceilTime)
                ? localDateTimeToDate(
                        LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0))
                : localDateTimeToDate(ceilTime);
    }

    /**
     * 校验日期，当月是否用户还有该套餐
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static Boolean checkTime(Date startTime, Date endTime) {
        LocalDateTime startLocal = DateUtil
                .convertDate2LocalDateTime(Optional.ofNullable(startTime).orElse(new Date()));
        LocalDateTime endLocal = DateUtil
                .convertDate2LocalDateTime(Optional.ofNullable(endTime).orElse(new Date()));
        return LocalDateTime.now().isBefore(endLocal) && LocalDateTime.now().isAfter(startLocal);
    }

    /**
     * 校验日期，当月是否用户还有该套餐
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public static Boolean checkStrTime(String startTime, String endTime) {
        SimpleDateFormat formatterT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if (StringUtils.isEmpty(startTime)) {
            startTime = convertDateToStr(new Date());
        }
        if (StringUtils.isEmpty(endTime)) {
            try {
                endTime = convertDateToStr(formatterT.parse("2099-08-01 00:00:00"));
            } catch (Exception e) {

            }
        }

        LocalDateTime startLocal = DateUtil
                .convertDate2LocalDateTime(convertStrToDate(startTime, DEFAULT_PATTERN));
        LocalDateTime endLocal = DateUtil
                .convertDate2LocalDateTime(convertStrToDate(endTime, DEFAULT_PATTERN));
        return LocalDateTime.now().isBefore(endLocal) && LocalDateTime.now().isAfter(startLocal);
    }

    /**校验日期，当月是否用户还有该套餐
     * @param startTime
     * @param endTime
     * @param pattern
     * @return
     */
    public static Boolean checkStrTime(String startTime, String endTime, String pattern) {
        SimpleDateFormat formatterT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        if (StringUtils.isEmpty(startTime)) {
            startTime = convertDateToStr(new Date());
        }
        if (StringUtils.isEmpty(endTime)) {
            try {
                endTime = convertDateToStr(formatterT.parse("2099-08-01 00:00:00"));
            } catch (Exception e) {

            }
        }

        LocalDateTime startLocal = DateUtil
                .convertDate2LocalDateTime(convertStrToDate(startTime, pattern));
        LocalDateTime endLocal = DateUtil
                .convertDate2LocalDateTime(convertStrToDate(endTime, pattern));
        return LocalDateTime.now().isBefore(endLocal) && LocalDateTime.now().isAfter(startLocal);
    }
    /**
     * @date: 2022年07月22
     * @description 判断当前时间是否是青海权益日
     */
    public static boolean getQhEquityDay(){
        //判断
        return false;
    }

    /**
     * 当前时间是否在时间指定范围内<br>
     *
     * @param time      被检查的时间
     * @param beginTime 起始时间
     * @param endTime   结束时间
     * @return 是否在范围内
     * @since 3.0.8
     */
    public static boolean isIn(LocalDateTime time, LocalDateTime beginTime, LocalDateTime endTime) {
        return beginTime.isBefore(time) && endTime.isAfter(time);
    }



    /**获取上周的开始和结束
     * @param date
     * @return
     */
    public static LocalDate[] getPreviousWeek(LocalDate date) {
        final int dayOfWeek = date.getDayOfWeek().getValue();
        final LocalDate from = date.minusDays(dayOfWeek + 6); // (dayOfWeek - 1) + 7
        final LocalDate to = date.minusDays(dayOfWeek);

        return new LocalDate[] { from, to };
    }

    /**获取上个月的开始和结束
     * @param date
     * @return
     */
    public static LocalDate[] getPreviousMonth(LocalDate date) {
        final LocalDate from = date.minusDays(date.getDayOfMonth() - 1).minusMonths(1);
        final LocalDate to = from.plusMonths(1).minusDays(1);

        return new LocalDate[] { from, to };
    }

    /**获取上一年的开始 和结束
     * @param date
     * @return
     */
    public static LocalDate[] getPreviousYear(LocalDate date) {
        LocalDate date1 = date.minusYears(1);
        final LocalDate from = date1.with(TemporalAdjusters.firstDayOfYear());
        final LocalDate to = date1.with(TemporalAdjusters.lastDayOfYear());

        return new LocalDate[] { from, to };
    }

    /**
     * 获取今天的剩余秒数
     * @return
     */
    public static long getUntilToTodayEnd() {
        LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        long seconds = ChronoUnit.SECONDS.between(LocalDateTime.now(),midnight);
        return seconds;
    }

    /**
     * 获取今天
     * @return
     */
    public static String getToday() {
        return format(LocalDateTime.now(), "yyyy-MM-dd");
    }

    /**判定当天是否是非工作日（周六 周天）
     * @return
     */
    public static boolean isNotWorkDay() {
        LocalDate localDate = LocalDate.now();
        DayOfWeek week = localDate.getDayOfWeek();
        if (week == DayOfWeek.SATURDAY || week == DayOfWeek.SUNDAY) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    /**
    * @param args
    * @throws ParseException
    */
    public static void main(String  [] args) throws Exception {

        System.out.println(DateUtil.convertDateToStr(
                DateUtil.convertStrToDate(DateUtil.currentFirstDayM(), DateUtil.DEFAULT_PATTERN),
                DateUtil.PATTERN_YYYYMMDDHH24MISS));
        //        LocalDate[] array1 = getPreviousYear(LocalDate.now());
        //        System.out.println(array1[0]);
        //        System.out.println(array1[1]);

        //        System.out.println(DateUtil.convertStrToDate("20220301"));
        //
        //        System.out.println(dateToLocalDate(dateAddMonth(new Date(), 12)));
        //        System.out.println(stringToLocalDate(currentYearLastDayM()));
        //        System.out.println(getYesterday());
        //        Date week = getMondayOfWeek(DateUtil.dateAdd(new Date(), 2));
        //        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //        System.out.println("本周周一: " + format.format(week));
        //        System.out.println("当前年月:" + getyyyyMMStr());
        //        System.out.println("昨天: " + getYesterday());
        //        System.out.println("本月第一天： " +  currentFirstDayM());
        //        System.out.println("本月最后一天： " +  currentLastDayM());
        //
        //        String sss = "20220325032745";
        //        System.out.println("昨天: " + DateUtil.convertStrToDate(sss, "yyyyMMddHHmmss"));

        //        System.out.println(DateUtil.getCurrentMonday().getTime() / 1000);
        //        System.out.println(DateUtil.getCurrentSaturday().getTime() / 1000);
        //        System.out.println(DateUtil.getSundayOfThisWeek().getTime() / 1000);
        //        System.out.println(DateUtil.getFirstDayOfMonth(new Date()));
        //
        //        System.out.println("本周周一: " + format.format(getCurrentMonday()));
//        System.out.println(getCurrentYear());
//        System.out.println(getCurrentQuarter());
//        System.out.println(getQuarterDate(2023, 4, 15));
//        System.out.println(UUIDUtils.getUUID());
//        System.out.println(getFirstTimeOfQuarter());
//        System.out.println(getLastTimeOfQuarter());
//        System.out.println(getFirstTimeOfDay());
//        System.out.println(getTemplateTime());
//        System.out.println(dateToString(getRemindTime(0, 10), "yyyy-MM-dd HH"));
//        System.out.println(getFirstTimeOfMonth());
//        System.out.println(getLastTimeOfMonth());
        System.out.println(getCurrentTime());

    }

    /**
     * 获取季度指定月份及日期
     * @param year
     * @param quarter
     * @param dayOfMonth
     * @return
     */
    public static String getQuarterDate(int year, int quarter, int dayOfMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, (quarter * 3) - 1);
        calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
        Date date = calendar.getTime();
        return dateToString(date, "yyyy-MM-dd");
    }

    public static int getCurrentYear() {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(Calendar.YEAR);
    }

    public static int getCurrentQuarter(){
        LocalDate today = LocalDate.now();
        int quarter = (today.getMonthValue() - 1) / 3 + 1;
        return quarter;
    }

    public static String getFirstTimeOfQuarter() {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        int quarter = (month / 3) + 1;
        calendar.set(Calendar.MONTH, (quarter - 1) * 3);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastTimeOfQuarter() {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        int quarter = (month / 3) + 1;
        calendar.set(Calendar.MONTH, quarter * 3 - 1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getFirstTimeOfDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastTimeOfDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getTemplateTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateToString(calendar.getTime(), "yyyy年MM月dd日 HH:mm:ss");
    }

    public static Date getRemindTime(Integer next, Integer hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_YEAR, next);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Date nextDay10Am = calendar.getTime();
        return nextDay10Am;
    }

    public static String getFirstTimeOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getCurrentTime() {
        Calendar calendar = Calendar.getInstance();
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getLastTimeOfMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return dateToString(calendar.getTime(), "yyyy-MM-dd HH:mm:ss");
    }


}
